<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<c:set var="ctx" value="${pageContext.request.contextPath}"/>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>角色</title>
    <jsp:include page="/common/backend_common.jsp" />
    <link rel="stylesheet" href="${ctx}/ztree/zTreeStyle.css" type="text/css">
    <link rel="stylesheet" href="${ctx}/assets/css/bootstrap-duallistbox.min.css" type="text/css">
    <script type="text/javascript" src="${ctx}/ztree/jquery.ztree.all.min.js"></script>
    <script type="text/javascript" src="${ctx}/assets/js/jquery.bootstrap-duallistbox.min.js"></script>
    <style type="text/css">
        .bootstrap-duallistbox-container .moveall, .bootstrap-duallistbox-container .removeall {
            width: 50%;
        }
        .bootstrap-duallistbox-container .move, .bootstrap-duallistbox-container .remove {
            width: 49%;
        }
    </style>
</head>
<body class="no-skin" youdao="bind" style="background: white">
<input id="gritter-light" checked="" type="checkbox" class="ace ace-switch ace-switch-5"/>
<div class="page-header">
    <h1>
        角色管理
        <small>
            <i class="ace-icon fa fa-angle-double-right"></i>
            维护角色与用户, 角色与权限关系
        </small>
    </h1>
</div>
<div class="main-content-inner">
    <div class="col-sm-3">
        <div class="table-header">
            角色列表&nbsp;&nbsp;
            <a class="green" href="#">
                <i class="ace-icon fa fa-plus-circle orange bigger-130 role-add"></i>
            </a>
        </div>
        <div id="roleList"></div>
    </div>
    <div class="col-sm-9">
        <div class="tabbable" id="roleTab">
            <ul class="nav nav-tabs">
                <li class="active">
                    <a data-toggle="tab" href="#roleAclTab">
                        角色与权限
                    </a>
                </li>
                <li>
                    <a data-toggle="tab" href="#roleUserTab">
                        角色与用户
                    </a>
                </li>
            </ul>
            <div class="tab-content">
                <div id="roleAclTab" class="tab-pane fade in active">
                    <ul id="roleAclTree" class="ztree"></ul>
                    <button class="btn btn-info saveRoleAcl" type="button">
                        <i class="ace-icon fa fa-check bigger-110"></i>
                        保存
                    </button>
                </div>

                <div id="roleUserTab" class="tab-pane fade" >
                    <div class="row">
                        <div class="box1 col-md-6">待选用户列表</div>
                        <div class="box1 col-md-6">已选用户列表</div>
                    </div>
                    <select multiple="multiple" size="10" name="roleUserList" id="roleUserList" >
                    </select>
                    <div class="hr hr-16 hr-dotted"></div>
                    <button class="btn btn-info saveRoleUser" type="button">
                        <i class="ace-icon fa fa-check bigger-110"></i>
                        保存
                    </button>
                </div>
            </div>
        </div>
    </div>
</div>
<div id="dialog-role-form" style="display: none;">
    <form id="roleForm">
        <table class="table table-striped table-bordered table-hover dataTable no-footer" role="grid">
            <tr>
                <td><label for="roleName">名称</label></td>
                <td>
                    <input type="text" name="name" id="roleName" value="" class="text ui-widget-content ui-corner-all">
                    <input type="hidden" name="id" id="roleId"/>
                </td>
            </tr>
            <tr>
                <td><label for="roleStatus">状态</label></td>
                <td>
                    <select id="roleStatus" name="status" data-placeholder="状态" style="width: 150px;">
                        <option value="1">可用</option>
                        <option value="0">冻结</option>
                    </select>
                </td>
            </tr>
            <td><label for="roleRemark">备注</label></td>
            <td><textarea name="remark" id="roleRemark" class="text ui-widget-content ui-corner-all" rows="3" cols="25"></textarea></td>
            </tr>
        </table>
    </form>
</div>

<!--角色列表模板-->
<script id="roleListTemplate" type="x-tmpl-mustache">
<ol class="dd-list ">
    {{#roleList}}
        <li class="dd-item dd2-item role-name" id="role_{{id}}" href="javascript:void(0)" data-id="{{id}}">
            <div class="dd2-content" style="cursor:pointer;">
            {{name}}
            <span style="float:right;">
                <a class="green role-edit" href="#" data-id="{{id}}" >
                    <i class="ace-icon fa fa-pencil bigger-100"></i>
                </a>
                &nbsp;
                <a class="red role-delete" href="#" data-id="{{id}}" data-name="{{name}}">
                    <i class="ace-icon fa fa-trash-o bigger-100"></i>
                </a>
            </span>
            </div>
        </li>
    {{/roleList}}
</ol>
</script>
<!-- /角色列表模板-->

<script id="selectedUsersTemplate" type="x-tmpl-mustache">
{{#userList}}
    <option value="{{id}}" selected="selected">{{username}}</option>
{{/userList}}
</script>

<script id="unSelectedUsersTemplate" type="x-tmpl-mustache">
{{#userList}}
    <option value="{{id}}">{{username}}</option>
{{/userList}}
</script>

<script type="text/javascript">
    $(function () {
        var roleMap = {};				//
        var lastRoleId = -1;			//上一次点击的角色的ID
        var selectFirstTab = true;		//是否选中第一个Tab选项（页面有“角色与权限”，“角色与用户”两个选项）
        var hasMultiSelect = false;		//是否多选
        
        var roleListTemplate = $("#roleListTemplate").html();
        Mustache.parse(roleListTemplate);
        var selectedUsersTemplate = $("#selectedUsersTemplate").html();
        Mustache.parse(selectedUsersTemplate);
        var unSelectedUsersTemplate = $("#unSelectedUsersTemplate").html();
        Mustache.parse(unSelectedUsersTemplate);
        
        loadRoleList();

        // zTree
        <!-- 树结构相关 开始 -->
        var zTreeObj = [];			// 保存权限信息
        var modulePrefix = 'm_';	// 权限模块前缀
        var aclPrefix = 'a_';		// 权限前缀
        var nodeMap = {};			// 保存“权限模块”信息
		/*
			为什么要把“权限”信息放到zTreeObj，要把”权限模块“信息放到nodeMap里面，再取出nodeMap一个个放到zTreeObj里面？
			这是因为首次在读取一个“权限模块的”时候，还不知道下面的层级结构是什么，所以后面会有一个刷新的过程，
			在刷新的过程里面会改掉它里面的值，所以暂时把“权限模块”的值放到nodeMap里面
			当递归执行完之后就是最终的数据了，这个时候在放进zTreeObj
		*/

		
		//加载角色列表 开始
        function loadRoleList() {
            $.ajax({
                url: "${ctx}/sys/role/list.json",
                success: function (result) {
                    if (result.ret) {
                        var rendered = Mustache.render(roleListTemplate, {roleList: result.data});
						//渲染首层
                        $("#roleList").html(rendered);
						//绑定单击事件
                        bindRoleClick();
                        //遍历角色数据，以【key:id，value:role】的格式保存到roleMap
						$.each(result.data, function(i, role) {
                            roleMap[role.id] = role;
                        });
                    } else {
                        showMessage("加载角色列表", result.msg, false);
                    }
                }
            });
        }
		//加载角色列表 结束
		
		//角色列表绑定单击事件开始
        function bindRoleClick() {
            //点击“修改角色”按钮事件开始
			$(".role-edit").click(function (e) {
                e.preventDefault();
                e.stopPropagation();
                var roleId = $(this).attr("data-id");
                $("#dialog-role-form").dialog({
                    model: true,
                    title: "修改角色",
                    open: function(event, ui) {
                        $(".ui-dialog-titlebar-close", $(this).parent()).hide();
                        //重置修改窗口
						$("#roleForm")[0].reset();
                        var targetRole = roleMap[roleId];
                        //填充要修改的角色的信息
						if (targetRole) {
                            $("#roleId").val(roleId);
                            $("#roleName").val(targetRole.name);
                            $("#roleStatus").val(targetRole.status);
                            $("#roleRemark").val(targetRole.remark);
                        }
                    },
                    buttons : {
                        "修改": function(e) {
                            e.preventDefault();
                            updateRole(false, function (data) {
                                $("#dialog-role-form").dialog("close");
                            }, function (data) {
                                showMessage("修改角色", data.msg, false);
                            })
                        },
                        "取消": function () {
                            $("#dialog-role-form").dialog("close");
                        }
                    }
                })
            });
			
			//点击角色列表选项事件开始
		   $(".role-name").click(function (e) {
               e.preventDefault();
               e.stopPropagation();
               //获取角色ID
			   var roleId = $(this).attr("data-id");
			   //设置选中的选项的样式
               handleRoleSelected(roleId);
            });
			//点击角色列表选项事件结束
        }
		//角色列表绑定单击事件结束
				
		//点击“添加角色”按钮事件开始
        $(".role-add").click(function () {
            $("#dialog-role-form").dialog({
                model: true,
                title: "新增角色",
                open: function(event, ui) {
                    $(".ui-dialog-titlebar-close", $(this).parent()).hide();
                    $("#roleForm")[0].reset();
                },
                buttons : {
                    "添加": function(e) {
                        e.preventDefault();
                        updateRole(true, function (data) {
                            $("#dialog-role-form").dialog("close");
                        }, function (data) {
                            showMessage("新增角色", data.msg, false);
                        })
                    },
                    "取消": function () {
                        $("#dialog-role-form").dialog("close");
                    }
                }
            })
        });
		//点击“添加角色”按钮事件结束
				
		//【添加、修改】角色方法开始
        function updateRole(isCreate, successCallback, failCallback) {
            $.ajax({
                url: isCreate ? "${ctx}/sys/role/save.json" : "${ctx}/sys/role/update.json",
                data: $("#roleForm").serializeArray(),
                type: 'POST',
                success: function(result) {
                    if (result.ret) {
                        loadRoleList();
                        if (successCallback) {
                            successCallback(result);
                        }
                    } else {
                        if (failCallback) {
                            failCallback(result);
                        }
                    }
                }
            })
        }
		//【添加、修改】角色方法结束
		
		
		
		//初始化zTree设置 开始
        var setting = {
            check: {
                enable: true,						
                chkDisabledInherit: true,
                chkboxType: {"Y": "ps", "N": "ps"}, //auto check 父节点 子节点
                autoCheckTrigger: true
            },
            data: {
                simpleData: {
                    enable: true,	
                    rootPId: 0				//指定顶层ID为0
                }
            },
            callback: {
                onClick: onClickTreeNode	//指定单击事件的函数
            }
        };
		//初始化zTree设置 结束
		
		// zTree绑定单击事件 开始
        function onClickTreeNode(e, treeId, treeNode) { 
            var zTree = $.fn.zTree.getZTreeObj("roleAclTree");
            zTree.expandNode(treeNode);
        }
        // zTree绑定单击事件 结束
				
		//点击角色列表加载权限 开始
        function handleRoleSelected(roleId) {
            //将上次选中的选项样式移除
			if (lastRoleId != -1) {
                var lastRole = $("#role_" + lastRoleId + " .dd2-content:first");
                lastRole.removeClass("btn-yellow");
                lastRole.removeClass("no-hover");
            }
			//设置选中的选项的样式
            var currentRole = $("#role_" + roleId + " .dd2-content:first");
            currentRole.addClass("btn-yellow");
            currentRole.addClass("no-hover");
            
			//更新“上次选中的选项ID”
			lastRoleId = roleId;

            $('#roleTab a:first').trigger('click');
            //如果选中的是第一个Tab选项（角色与权限）的话，就加载权限列表
			if (selectFirstTab) {
                loadRoleAcl(roleId);
            }
        }
		//点击角色列表加载权限 结束
		
		//根据角色的ID加载权限 开始
        function loadRoleAcl(selectedRoleId) {
            if (selectedRoleId == -1) {
                return;
            }
            $.ajax({
                url: "${ctx}/sys/role/roleTree.json",
                data : {
                    roleId: selectedRoleId
                },
                type: 'POST',
                success: function (result) {
                    if (result.ret) {
                        renderRoleTree(result.data);
                    } else {
                        showMessage("加载角色权限数据", result.msg, false);
                    }
                }
            });
        }
		//根据角色的ID加载权限 结束

		//渲染角色zTree 开始
        function renderRoleTree(aclModuleList) {
			//清空树节点数据
            zTreeObj = [];	
			//这里面将会把nodeMap里面的数据准备好
            recursivePrepareTreeData(aclModuleList);
			//通过nodeMap生成zTreeObj
            for(var key in nodeMap) {
                zTreeObj.push(nodeMap[key]);
            }
            $.fn.zTree.init($("#roleAclTree"), setting, zTreeObj);
        }
		//渲染角色zTree 结束
		
		//递归准备nodeMap数据，将“权限”数据放入zTreeObj，将“权限模块”数据放入nodeMap
        function recursivePrepareTreeData(aclModuleList) {
            // prepare nodeMap
            if (aclModuleList && aclModuleList.length > 0) {
				//遍历权限模块
                $(aclModuleList).each(function(i, aclModule) {
					//是否勾选
                    var hasChecked = false;
					//如果“权限模块”包含权限，则将“权限”放入zTreeObj
                    if (aclModule.aclList && aclModule.aclList.length > 0) {
						//遍历权限，将权限保存到zTreeObj对象，后面提供给权限模块使用
                        $(aclModule.aclList).each(function(i, acl) {
                            zTreeObj.push({
                                id: aclPrefix + acl.id,	
                                pId: modulePrefix + acl.aclModuleId,
                                name: acl.name + ((acl.type == 1) ? '(菜单)' : ''),	//如果是菜单，就添加“菜单"标记
                                chkDisabled: !acl.hasAcl,							//如果该“权限模块”没有“权限”，就禁用单选框
                                checked: acl.checked,
                                dataId: acl.id
                            });
							
							//如果Acl是选中状态的话，就设置hasChecked为true，代表下面有权限了，就需要被勾选
                            if(acl.checked) {
                                hasChecked = true;
                            }
                        });
                    }

					//对“权限模块”进行处理
                    if ((aclModule.aclModuleList && aclModule.aclModuleList.length > 0) ||
                        (aclModule.aclList && aclModule.aclList.length > 0)) {
                        
						//将“权限模块”保存到nodeMap对象
						nodeMap[modulePrefix + aclModule.id] = {
                            id : modulePrefix + aclModule.id,
                            pId: modulePrefix + aclModule.parentId,
                            name: aclModule.name,
                            open: hasChecked
                        };
						
						//如果当前模块hasChecked=true（勾选）的话，那么上一层也应该hasChecked=true（勾选）
                        var tempAclModule = nodeMap[modulePrefix + aclModule.id]; //默认值给了当前“权限模块”
                        //如果当前“权限模块”是勾选状态，并且不是空的时候	
						while(hasChecked && tempAclModule) {
                            //这里tempAclModule会变，所有要判断是否可用
							if(tempAclModule) {
                                nodeMap[tempAclModule.id] = {
                                    id: tempAclModule.id,
                                    pId: tempAclModule.pId,
                                    name: tempAclModule.name,
                                    open: true
                                }
                            }
							
							//处理完了当前模块，就要处理上一层的“权限模块”
                            tempAclModule = nodeMap[tempAclModule.pId];
                        }
                    }
					//执行递归
                    recursivePrepareTreeData(aclModule.aclModuleList);
                });
            }
        }
        //递归准备nodeMap数据，将“权限”数据放入zTreeObj，将“权限模块”数据放入nodeMap
		
		// 获取zTree勾选的所有节点的ID 开始
        function getTreeSelectedId() {
            var treeObj = $.fn.zTree.getZTreeObj("roleAclTree");
            var nodes = treeObj.getCheckedNodes(true);
            var v = "";
            for(var i = 0; i < nodes.length; i++) {
				//如果选中的节点是以“权限”前缀的话再进行处理
                if(nodes[i].id.startsWith(aclPrefix)) {
                    v += "," + nodes[i].dataId;
                }
            }
			//因为每次都在前面添加了个“,”逗号，所以我们每次从下标为1的字符串开始取
            return v.length > 0 ? v.substring(1): v;
        }
		// 获取zTree勾选的所有节点的ID 结束	
		
		
		//保存角色与权限点的关系 开始
        $(".saveRoleAcl").click(function (e) {
            e.preventDefault();
            // 判断是否选择了角色
			if (lastRoleId == -1) {
                showMessage("保存角色与权限点的关系", "请现在左侧选择需要操作的角色", false);
                return;
            }            			
			$.ajax({
                url: "${ctx}/sys/role/changeAcls.json",
                data: {
                    roleId: lastRoleId,
                    aclIds: getTreeSelectedId()
                },
                type: 'POST',
                success: function (result) {
                    if (result.ret) {
                        showMessage("保存角色与权限点的关系", "操作成功", false);
                    } else {
                        showMessage("保存角色与权限点的关系", result.msg, false);
                    }
                }
            });
        });
		//保存角色与权限点的关系 结束
		
		
		//Tab选项卡的点击事件 开始
        $("#roleTab a[data-toggle='tab']").on("shown.bs.tab", function(e) {
            //如果没有选中“角色”
			if(lastRoleId == -1) {
                showMessage("加载角色关系","请先在左侧选择操作的角色", false);
                return;
            }
			//如果选择的是【角色与权限】选项卡的话，就加载角色的权限树
            if (e.target.getAttribute("href") == '#roleAclTab') {
                selectFirstTab = true;
                loadRoleAcl(lastRoleId);
            } else {
                selectFirstTab = false;
                loadRoleUser(lastRoleId);
            }
        });
		//Tab选项卡的点击事件 结束
		
		//加载角色的用户 开始
        function loadRoleUser(selectedRoleId) {
            $.ajax({
                url: "${ctx}/sys/role/users.json",
                data: {
                    roleId: selectedRoleId
                },
                type: 'POST',
                success: function (result) {
                    if (result.ret) {
						//渲染已选用户列表
                        var renderedSelect = Mustache.render(selectedUsersTemplate, {userList: result.data.selected});
						//渲染未选的用户列表
                        var renderedUnSelect = Mustache.render(unSelectedUsersTemplate, {userList: result.data.unselected});
                        $("#roleUserList").html(renderedSelect + renderedUnSelect);

						//判断是否初始化过列表
                        if(!hasMultiSelect) {
                            $('select[name="roleUserList"]').bootstrapDualListbox({
                                showFilterInputs: false,
                                moveOnSelect: false,
                                infoText: false
                            });
                            hasMultiSelect = true;
                        } else {
                            $('select[name="roleUserList"]').bootstrapDualListbox('refresh', true);
                        }
                    } else {	
                        showMessage("加载角色用户数据", result.msg, false);
                    }
                }
            });
        }
		//加载角色的用户 结束
		
		//保存角色和用户的关系 开始
        $(".saveRoleUser").click(function (e) {
            e.preventDefault();
            if (lastRoleId == -1) {
                showMessage("保存角色与用户的关系", "请现在左侧选择需要操作的角色", false);
                return;
            }
            $.ajax({
                url: "${ctx}/sys/role/changeUsers.json",
                data: {
                    roleId: lastRoleId,
					//如果当前的值不存在的话就返回空字符串
                    userIds: $("#roleUserList").val() ? $("#roleUserList").val().join(",") : ''
                },
                type: 'POST',
                success: function (result) {
                    if (result.ret) {
                        showMessage("保存角色与用户的关系", "操作成功", false);
                    } else {
                        showMessage("保存角色与用户的关系", result.msg, false);
                    }
                }
            });
        });
		//保存角色和用户的关系 结束
	});
</script>
</body>
</html>
